"""
Copyright (c) 2022 Huawei Technologies Co.,Ltd.

openGauss is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:

          http://license.coscl.org.cn/MulanPSL2

THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
"""
"""
Case Type   : gs_ctl
Case Name   : postgresql.conf里面再include其他配置文件时,备机全量build
Create At   : 2023/02/23
Owner       : opentestcase016
Description :
    1 获取postgresql.conf的replconninfo信息
    2 修改postgresql.conf为postgresql.base.conf，
      创建新的postgresql.conf文件,并配置include以及replconninfo信息
    3 移出postgresql.base.conf,并修改postgresql.conf,使用-q参数执行备机build
    4 移动回postgresql.base.conf 文件 ，取消postgresql.conf 文件中include的注释，
      启动数据库
    5 恢复数据库
Expect      :
    1 成功
    2 成功
    3 build成功
    4 启动成功
    5 成功
History     :
"""

import unittest
import os

from yat.test import Node
from yat.test import macro

from testcase.utils.CommonSH import CommonSH
from testcase.utils.CommonSH import Constant
from testcase.utils.Logger import Logger
from testcase.utils.Common import Common

PrimarySh = CommonSH('PrimaryDbUser')


@unittest.skipIf(1 == PrimarySh.get_node_num(), '单机环境不执行')
class ToolsTestCase(unittest.TestCase):
    def setUp(self):
        self.log = Logger()
        self.log.info(f'----{os.path.basename(__file__)} end----')
        self.primary_sh = CommonSH('PrimaryDbUser')
        self.standby_sh = CommonSH('Standby1DbUser')
        self.standby_node = Node('Standby1DbUser')
        self.constant = Constant()
        self.comm = Common()
        self.move_path = os.path.join(macro.DB_BACKUP_PATH, 'gs_ctl_Case0172')
        self.base_config_name = 'postgresql.base.conf'
        get_config = self.standby_sh.execut_db_sql('show config_file;')
        self.config_file = get_config.strip().splitlines()[-2].strip()
        self.log.info(self.config_file)
        (self.config_file_path, self.config_file_name) = \
            os.path.split(self.config_file)

    def test_gs_ctl(self):
        text = '--step1:获取postgresql.conf的replconninfo信息 expect:成功--'
        self.log.info(text)
        self.replconninfo = []
        i = 1
        while i < 9:
            get_info = self.standby_sh.execut_db_sql(f'show replconninfo{i};')
            repl_info = get_info.strip().splitlines()[-2].strip()
            if not repl_info:
                break
            else:

                i = i + 1
                self.replconninfo.append("replconninfo" + str(i) + " = '" +
                                         repl_info + "'")
        self.log.info(self.replconninfo)

        text = '--step2:修改postgresql.conf文件名为postgresql.base.conf,' \
               '创建新的postgresql.conf文件,并配置include以及replconninfo信息 ' \
               'expect:成功--'
        self.log.info(text)
        mkdir_cmd = f'if [ ! -d {self.move_path} ];' \
                    f'then mkdir {self.move_path};fi'
        self.log.info(mkdir_cmd)
        result = self.standby_node.sh(mkdir_cmd).result()
        self.log.info(result)
        self.assertIn('', result, '执行失败' + text)
        bak_conf = f'cp {self.config_file} ' \
                   f'{self.move_path}/{self.config_file_name}_bak'
        self.log.info('备份配置文件' + bak_conf)
        result = self.standby_node.sh(bak_conf).result()
        self.log.info(result)
        self.assertIn('', result, '执行失败' + text)
        cmd1 = f'mv {self.config_file} ' \
               f'{self.config_file_path}/{self.base_config_name}'
        self.log.info(cmd1)
        result1 = self.standby_node.sh(cmd1).result()
        self.log.info(result1)
        self.assertIn('', result1, '执行失败' + text)
        conf_cmd1 = f"echo \"include '{self.base_config_name}'\">>" \
                    f"{self.config_file}"
        self.log.info(conf_cmd1)
        conf_res = self.standby_node.sh(conf_cmd1).result()
        self.log.info(conf_res)
        self.assertIn('', conf_res, '执行失败' + text)
        for repl_infor in self.replconninfo:
            conf_cmd2 = f'echo "{repl_infor}" >>{self.config_file}'
            self.log.info(conf_cmd2)
            result2 = self.standby_node.sh(conf_cmd2).result()
            self.log.info(result2)
            self.assertIn('', result2, '执行失败' + text)

        text = '--step3:移出postgresql.base.conf,并修改postgresql.conf,' \
               '执行备机build expect:成功 --'
        self.log.info(text)
        move_cmd = f'mv {self.config_file_path}/{self.base_config_name} ' \
                   f'{self.move_path}'
        self.log.info(move_cmd)
        result = self.standby_node.sh(move_cmd).result()
        self.log.info(result)
        self.assertIn('', result, '执行失败' + text)
        modify_cmd = f"sed -i 's/^include/#include/g' {self.config_file}"
        self.log.info(modify_cmd)
        result = self.standby_node.sh(modify_cmd).result()
        self.log.info(result)
        self.assertIn('', result, '执行失败' + text)
        build_msg = self.standby_sh.execute_gsctl('build', 'success',
                                                  param='-q')
        self.log.info(build_msg)
        self.assertTrue(build_msg)

        text = '--step4:移动回postgresql.base.conf 文件,' \
               '取消postgresql.conf文件中include的注释，启动数据库' \
               'expect:成功--'
        self.log.info(text)
        cp_cmd = f'cp {self.move_path}/{self.base_config_name} ' \
                 f'{self.config_file_path}'
        self.log.info(cp_cmd)
        result = self.standby_node.sh(cp_cmd).result()
        self.log.info(result)
        self.assertIn('', result, '执行失败' + text)
        modify_cmd = f"sed -i 's/^#include/include/g' {self.config_file}"
        self.log.info(modify_cmd)
        result = self.standby_node.sh(modify_cmd).result()
        self.log.info(result)
        self.assertIn('', result, '执行失败' + text)
        start_msg = self.standby_sh.start_db_instance(mode="standby")
        self.log.info(start_msg)
        self.assertTrue(start_msg)

    def tearDown(self):
        text = '--step5:恢复数据库 expect:成功--'
        self.log.info(text)
        self.log.info('清理postgresql.base.conf 文件')
        rm_cmd = f'rm -rf {self.config_file_path}/{self.base_config_name}'
        self.log.info(rm_cmd)
        result = self.standby_node.sh(rm_cmd).result()
        self.log.info(result)
        mv_cmd = f'mv {self.move_path}/{self.config_file_name}_bak ' \
                 f'{self.config_file}'
        self.log.info(mv_cmd)
        result = self.standby_node.sh(mv_cmd).result()
        self.log.info(result)
        result = self.primary_sh.restart_db_cluster(True)
        flg = self.constant.START_SUCCESS_MSG in result \
              or 'Degrade' in result
        self.assertTrue(flg)
        cmd = f'rm -rf {self.move_path}'
        self.log.info(cmd)
        result = self.standby_node.sh(cmd).result()
        self.assertIn('', result, '清理环境失败')
        self.log.info(f'----{os.path.dirname(__file__)} end----')
